#include "sign_kernel.h"
#include<iostream>
#include<vector>
#include<algorithm>

/**********************************************
 * @作者        : hqf
 * @功能        : 执行cmd结果保存到resvec
 * @返回值      : 结果个数
 **********************************************/
int32_t myexec(const char *cmd, std::vector<std::string> &resvec)
{
    char tmp[1024]; //设置一个合适的长度，以存储每一行输出
    FILE *pp = popen(cmd, "r"); //建立管道
    if (!pp) {
        return -1;
    }
    resvec.clear();
    while (fgets(tmp, sizeof(tmp), pp) != NULL) {
        if (tmp[strlen(tmp) - 1] == '\n') {
            tmp[strlen(tmp) - 1] = '\0'; //去除换行符
        }
        resvec.push_back(tmp);
    }
    pclose(pp); //关闭管道
    return resvec.size();
}

/**********************************************
 * @作者        : hqf
 * @功能        : 非堵塞执行cmdstring
 * @返回值      : 结果个数
 **********************************************/
int systemNoBlock(const char * cmdstring) 
{ 
    pid_t pid;
    int status = 0;
    if(cmdstring == nullptr){        
        return -1;
    }
    if((pid = fork())<0) {
        status = -1;
    } else if(pid == 0) {
        execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
        _exit(127); //子进程正常执行则不会执行此语句
    }
    return status;
}

/* 加载文件到内存 */
bool getFileInfo(const char* filename, std::string& buffer)
{
    int fd = 0;
    int len = 0;
    char buf[1024];
    bool ret = false;

    fd = open(filename, O_RDWR);
    SIGNWAY_ERROR_GOTO(fd < 0, RETURN, "%s open failed", filename);

    while (true) {
        memset(buf, 0, sizeof(buf));
        len = read(fd, buf, sizeof(buf));
        SIGNWAY_ERROR_GOTO(len < 0, RETURN, "%s read failed", filename);
        if (len == 0) {
            break;
        }
        buffer += buf;
    }
    ret = true;
RETURN:
    if (fd >= 0) {
        close(fd);
    }
    return ret;
}

/* 文件filename更新为buffer */
bool updateFile(const char* filename, std::string buf)
{
    int fd = 0;
    int ret = 0;
    std::string cmd;
    std::string buffer = buf;

    fd = open("temp", O_CREAT|O_RDWR, 0644);
    SIGNWAY_ERROR_GOTO(fd < 0, RETURN, "temp open failed");

    ret = write(fd, buffer.c_str(), buffer.size());
    SIGNWAY_ERROR_GOTO(ret != (int)buffer.size(), RETURN, "ret != buffer.size()");

    cmd = "mv ";
    cmd += filename;
    cmd += " ";
    cmd += filename;
    cmd += ".bck";
    system(cmd.c_str());

    cmd = "mv temp ";
    cmd += filename;
    system(cmd.c_str());
    SIGNWAY_LOGI("%s", cmd.c_str());

    if (fd > 0) {
        close(fd);
    }
    return true;

RETURN:
    if (fd > 0) {
        close(fd);
    }
    return false;
}

template <typename T>
struct Printf {
    void operator()(T data) {
        std::cout << data << " ";
    }
};

std::string getFileName(std::string srcFileHead, std::string destFileHead, std::string fileName, int value) 
{
    std::string idStr = fileName.substr(srcFileHead.length(), fileName.length() - srcFileHead.length());
    int id = atoi(idStr.c_str()) + value;

    // SIGNWAY_LOGI("\r\n fileName = %s\r\n value = %d\r\n idStr = %s\r\n id = %d", fileName.c_str(), value, idStr.c_str(), id);

    return destFileHead + std::to_string(id);
}

/* 自动重命名小工具 filehead[begin,end]->filehead[begin+value,end+value]*/
bool automaticRenamingWidget(const char* srcFileHead, const char* destFileHead, int value)
{
    std::string cmd;
    std::vector<std::string> srcFileList;
    /* 在当前目录创建一个bck目录 */
    system("mkdir bck");
    /* 获取srcFileHead开头的文件 @{ */
    cmd = "ls -1 ";
    cmd += srcFileHead;
    cmd += "*";
    myexec(cmd.c_str(), srcFileList);
    /* 获取srcFileHead开头的文件 @} */

    for (auto &file : srcFileList)
    {
        /* 分割后缀名和文件名 */
        int index = file.find_last_of(".");
        std::string filename;
        std::string filetype;

        if (index == std::string::npos) {
            /* 无类型名字文件 */
            filename = file;
            filetype = "";
        } else {
            filename = file.substr(0, index);
            filetype = file.substr(index, file.size() - index);
        }
        // SIGNWAY_LOGI("%s, %s", filename.c_str(), filetype.c_str());
        cmd = "cp ";
        cmd += file + " ";
        cmd += "bck/";
        cmd += getFileName(srcFileHead, destFileHead, filename, value);
        cmd += filetype;
        SIGNWAY_LOGI("%s", cmd.c_str());
        system(cmd.c_str());
    }

    // for_each(srcFileList.begin(), srcFileList.end(), Printf<std::string>());
    // std::cout << "\r\n";
}